package com.upush;

import static android.content.Context.NOTIFICATION_SERVICE;

import android.app.Application;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import android.widget.Toast;

import androidx.core.app.NotificationCompat;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;

import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.umeng.message.MsgConstant;
import com.umeng.message.PushAgent;
import com.umeng.message.UmengMessageHandler;
import com.umeng.message.UmengNotificationClickHandler;
import com.umeng.message.api.UPushRegisterCallback;
import com.umeng.message.entity.UMessage;

import org.android.agoo.huawei.HuaWeiRegister;
// import org.android.agoo.oppo.OppoRegister;
// import org.android.agoo.vivo.VivoRegister;
import org.android.agoo.xiaomi.MiPushRegistar;

import java.util.Map;

public class UMPushHelper {
    private static final String TAG = "PushHelper";
    private Context context;
    public ReactApplicationContext reactContext;
    public String deviceToken;


    private UMPushHelper() {
    }

    private static volatile UMPushHelper instance = null;

    public static UMPushHelper getInstance() {
        synchronized (UMPushHelper.class) {
            if (instance == null) {
                instance = new UMPushHelper();
            }
            return instance;
        }
    }

    public int logo = R.drawable.ic_launcher;


    public UMPushHelper setContext(Context context) {
        this.context = context;
        return this;
    }

    public UMPushHelper setHuaWeiRegister() {
        if (this.context != null) {
            HuaWeiRegister.register((Application) context);
        }
        return this;
    }

    public UMPushHelper setMiPushRegistar(String xiaomiId, String xiaomiKey) {
        if (this.context != null) {
            MiPushRegistar.register(context, xiaomiId, xiaomiKey);
        }
        return this;
    }

    public UMPushHelper setOppoRegister(String appKey, String appSecret) {
        if (this.context != null) {
            // OppoRegister.register(context, appKey, appSecret);
        }

        return this;
    }

    public UMPushHelper setVivoRegister() {
        if (this.context != null) {
            // VivoRegister.register(context);
        }
        return this;
    }


    public static class ChannelDescription {
        String id;//渠道id
        CharSequence name;//渠道name
        Uri sound;//渠道音频

        private ChannelDescription() {
        }

        public ChannelDescription(String id, CharSequence name, Uri sound) {
            this.id = id;
            this.name = name;
            this.sound = sound;
        }

    }

    public static abstract class PushAgentOpitons {
        public PushAgentOpitons() {
        }

        protected abstract int getLogo();

        protected abstract ChannelDescription getChannelDescription(UMessage msg);


    }

    public UMPushHelper setPushAgent(PushAgentOpitons options) {
        if (options != null) {
            int logo = options.getLogo();
            if (logo != 0) {
                instance.logo = logo;
            }
        }

        PushAgent pushAgent = PushAgent.getInstance(context);
        /**
         * 设置App处于前台时不显示通知
         * 如果您的应用在前台，您可以设置不显示通知消息。
         * 默认情况下，应用在前台是显示通知的。开发者更改前台通知显示设置后，会根据更改生效。
         */
        // pushAgent.setNotificationOnForeground(false);
        /**
         * 服务端控制声音
         */
        pushAgent.setNotificationPlaySound(MsgConstant.NOTIFICATION_PLAY_SERVER);

        /**
         * 客户端允许呼吸灯点亮
         */
        pushAgent.setNotificationPlayLights(MsgConstant.NOTIFICATION_PLAY_SDK_ENABLE);

        /**
         *自定义点击通知时的打开动作
         * 开发者可自定义点击通知的后续动作，自定义行为在UMessage.custom字段。
         * 在推送通知消息时，在“后续动作”中的“自定义行为”中输入相应的值或代码即可实现。
         * 若开发者需要处理自定义行为，则可以重写方法dealWithCustomAction()，示例代码：
         */
        pushAgent.setNotificationClickHandler(notificationClickHandler);

        /**
         * 设置显示通知的数量
         * 可以设置最多显示通知的条数，当显示数目大于设置值时，若再有新通知到达，会移除一条最早的通知
         */
        pushAgent.setDisplayNotificationNumber(10);

        /**
         * 默认情况下，同一台设备在1分钟内收到同一个应用的多条通知时，不会重复提醒，可以通过如下方法来设置冷却时间：
         */
        //pushAgent.setMuteDurationSeconds(3);

        /**
         * 自定义通知样式
         * UmengMessageHandler类负责处理消息，包括通知和自定义消息。
         * 其中，getNotification方法返回通知样式。若默认展示样式不符合开发者的需求，可通过重写该方法自定义展示样式
         */
        pushAgent.setMessageHandler(new UmengMessageHandler() {
            /**
             * 自定义通知样式，此方法可以修改通知样式等
             * @param context
             * @param msg
             * @return
             */
            @Override
            public Notification getNotification(Context context, UMessage msg) {
                sendNotificationEvent(msg.extra, 0);
                if (options != null) return super.getNotification(context, msg);
                ChannelDescription channelDescription = options.getChannelDescription(msg);
                if (channelDescription == null) return super.getNotification(context, msg);

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    NotificationManager notificationManager = (NotificationManager) instance.context.getSystemService(NOTIFICATION_SERVICE);
                    NotificationChannel channel = notificationManager.getNotificationChannel(channelDescription.id);
                    if (channel == null) {
                        channel = new NotificationChannel(channelDescription.id, channelDescription.name, NotificationManager.IMPORTANCE_HIGH);
                    }
                    channel.setSound(channelDescription.sound, Notification.AUDIO_ATTRIBUTES_DEFAULT);//Notification.AUDIO_ATTRIBUTES_DEFAULT
                    //notificationChannel.setImportance(NotificationManager.IMPORTANCE_HIGH);
                    channel.enableVibration(true);
                    channel.setVibrationPattern(new long[]{0, 1000, 1000, 1000});//震动
                    channel.setLightColor(Color.BLUE);
                    notificationManager.createNotificationChannel(channel);
                }
                Notification notification = new NotificationCompat.Builder(context, channelDescription.id)
                        .setSound(channelDescription.sound)
                        .setVibrate(new long[]{0, 1000, 1000, 1000})//震动
                        //LED灯的使用涉及到以下一个属性：
                        //ledARGB ——- 控制LED灯的颜色
                        //ledOnMS ——- 控制LED灯亮起的时间，以毫秒为单位
                        //ledOffMS ——? 控制LED灯熄灭的时间，以毫秒为单位
                        .setLights(Color.BLUE, 1000, 1000)
                        .setAutoCancel(true)
                        .setPriority(NotificationCompat.PRIORITY_HIGH)
                        .setContentTitle(msg.title)
                        .setContentText(msg.text)
                        .setWhen(System.currentTimeMillis())
                        .setSmallIcon(instance.logo)
                        .setOngoing(true)
                        .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), instance.logo))
                        //.setContentIntent(pendingIntent)
                        //在build()方法之前还可以添加其他方法
                        .build();
                return notification;

            }
        });


        return this;
    }

    public UMPushHelper setPushAgent() {
        return this.setPushAgent(null);
    }

    public interface RegisterCallback {
        void onSuccess(String deviceToken);

        void onFailure(String errCode, String errDesc);
    }

    /**
     * 在UMConfigure.init方法后调用注册接口，注册成功后可获取deviceToken
     */
    public UMPushHelper register(RegisterCallback registerCallback) {
        PushAgent pushAgent = PushAgent.getInstance(context);
        pushAgent.register(new UPushRegisterCallback() {
            @Override
            public void onSuccess(String deviceToken) {
                //注册成功会返回deviceToken deviceToken是推送消息的唯一标志
                Log.i(TAG, "注册成功 deviceToken:" + deviceToken);
                UMPushHelper.getInstance().deviceToken = deviceToken;
                registerCallback.onSuccess(deviceToken);
            }

            @Override
            public void onFailure(String errCode, String errDesc) {
                Log.e(TAG, "注册失败 " + "code:" + errCode + ", desc:" + errDesc);
                registerCallback.onFailure(errCode, errDesc);
            }
        });
        return this;
    }

    private UmengNotificationClickHandler notificationClickHandler = new UmengNotificationClickHandler() {
        @Override
        public void dealWithCustomAction(Context context, UMessage msg) {
            super.dealWithCustomAction(context, msg);
            Log.i(TAG, "dealWithCustomAction: " + msg.getRaw().toString());
            String packageName = instance.context.getPackageName();
            PackageManager packageManager = instance.context.getPackageManager();
            Intent intent = new Intent();
            intent = packageManager.getLaunchIntentForPackage(packageName);
            if (intent == null) {
                Toast.makeText(instance.context, "未安装", Toast.LENGTH_LONG).show();
            } else {
                instance.context.startActivity(intent);
            }
            sendNotificationEvent(msg.extra, 1);
        }

    };

    private void sendNotificationEvent(Map<String, String> extraMap, int pop) {
        WritableMap params = Arguments.createMap();
        params.putInt("pop", pop);
        if (extraMap != null) {
            for (Map.Entry<String, String> extra : extraMap.entrySet()) {
                params.putString(extra.getKey(), extra.getValue());
            }
        }

        this.reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit("UMPushNotificationEvent", params);
    }

}
